﻿using MongoDB.Driver;
using Sustainalytics.Entities.RiskRatings;
using Sustainalytics.RiskRatings.Service.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;

namespace Sustainalytics.RiskRatings.Service.Controllers.Company
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/v1/company/{companyId}")]
    public class EventController : ApiController
    {
        private readonly IMongoCollection<EventIndicator> _eventCollection;
        private readonly IMongoCollection<Incident> _incidentCollection;

        public EventController(IMongoCollection<EventIndicator> eventCollection, IMongoCollection<Incident> incidentCollection)
        {
            _eventCollection = eventCollection;
            _incidentCollection = incidentCollection;
        }

        [Route("event/{code}")]
        public async Task<HttpResponseMessage> Get(Guid companyId, string code)
        {
            code = code.Replace("_", ".");
            var @event = await _eventCollection.Find(e => e.CompanyId == companyId && e.CanvasCode == code).FirstOrDefaultAsync().ConfigureAwait(false);

            if (@event == null)
                return Request.CreateResponse(System.Net.HttpStatusCode.NotFound);

            var incidents = await _incidentCollection.Find(i => i.CompanyId == companyId && i.EventIndicatorId == @event.Id).ToListAsync().ConfigureAwait(false);

            HashSet<string> addresses = new HashSet<string>();
            HashSet<string> tags = new HashSet<string>();
            incidents.ForEach(i =>
            {
                if (!addresses.Contains(i.Location.Address)) { addresses.Add(i.Location.Address); }
                if (!tags.Contains(i.MainTag)) { tags.Add(i.MainTag); }
            });

            @event.LocationsText = addresses.Any() ? addresses.Aggregate((a, b) => a + ", " + b) : string.Empty;
            @event.Tags = tags.Any() ? tags.Aggregate((a, b) => a + ", " + b) : string.Empty;

            return Request.CreateResponse(System.Net.HttpStatusCode.OK, new
            {
                @event.CompanyId,
                Code = @event.CanvasCode.Replace(".", "_"),
                @event.Name,
                @event.Outlook,
                @event.EventCategory,
                @event.EventCategoryText,
                @event.ControversySummary,
                @event.EventJustification,
                @event.OutlookLabel,
                @event.OutlookText,
                @event.OutlookComments,
                @event.LocationsText,
                @event.Tags,
                Incidents = incidents.GroupBy(x => x.IncidentId).Select(g =>
                {
                    var result = new IncidentListDto();
                    var mainIncident = g.FirstOrDefault(x => x.IsMain);
                    result.MainIncident = new IncidentDto
                    {
                        Name = mainIncident?.Name,
                        IncidentDate = mainIncident?.IncidentDate,
                        Date = mainIncident?.IncidentDate.ToString("d MMMM yyyy"),
                        Source = mainIncident?.Source,
                        ExternalUrl = mainIncident?.ExternalUrl
                    };
                    result.Updates = g.Where(x => !x.IsMain).OrderByDescending(x => x.IncidentDate).Select(
                        x => new IncidentDto
                        {
                            Name = x?.Name,
                            Date = x?.IncidentDate.ToString("d MMMM yyyy"),
                            Source = x?.Source,
                            ExternalUrl = x?.ExternalUrl
                        });
                    return result;
                }).OrderByDescending(x => x.MainIncident.IncidentDate)
            });
        }
    }
}